//
//  HACNodesComponent.m
//  HStockCharts
//
//  Created by Hotacool on 2018/9/21.
//

#import "HACNodesComponent.h"

CGFloat refreshOffsetX = 30;
static const CGFloat kTimeBarHeight = 16;
#define defaultBkColor [UIColor colorWithWhite:0.9 alpha:0.5]
@interface HACNodesComponent () <UIGestureRecognizerDelegate, UIScrollViewDelegate>
@property (nonatomic, strong, readwrite) UIScrollView *contentScroll;
@property (nonatomic, strong, readwrite) UILabel *xCursorLabelUp; // y轴的文字提示
@property (nonatomic, strong, readwrite) UILabel *xCursorLabelDown; // y轴的文字提示
@property (nonatomic, strong, readwrite) UILabel *yCursorLabelLeft; // x轴的文字提示
@property (nonatomic, strong, readwrite) UILabel *yCursorLabelRight; // x轴的文字提示
@property (nonatomic, strong, readwrite) CAShapeLayer *focusLayer;
@property (nonatomic, strong, readwrite) CAShapeLayer *focusPointLayer;

@end

@implementation HACNodesComponent {
    NSTimer *_focusTimer;
}
- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.backgroundColor = [UIColor clearColor];
        _nodeDic = [NSMutableDictionary dictionaryWithCapacity:1];
        [self setUp];
    }
    return self;
}

- (void)setData:(HACChartData *)data {
    _data = data;
    [self.nodeDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, HACChartNode* _Nonnull node, BOOL * _Nonnull stop) {
        [node setData:data];
    }];
    [self setUpMarketTimeBarWithTimeArray:nil];
}

- (void)setVisualCount:(NSInteger)visualCount {
    _visualCount = visualCount;
    [self.nodeDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, HACChartNode * _Nonnull obj, BOOL * _Nonnull stop) {
        obj.visualCount = visualCount;
    }];
}

- (UIView *)marketTimeBar {
    if (!_marketTimeBar) {
        _marketTimeBar = [[UIView alloc] initWithFrame:CGRectZero];
    }
    return _marketTimeBar;
}
- (void)setUpMarketTimeBarWithTimeArray:(NSArray*)timesArray {//暂时，固定数目
    [self addSubview:self.marketTimeBar];
    if (!timesArray || timesArray.count == 0) {
        timesArray = @[@"9:30", @"11:30", @"15:00"];
    } else {
        if (timesArray.count == 2) {
            timesArray = @[timesArray.firstObject, @"", timesArray.lastObject];
        } else if (timesArray.count == 4) {
            timesArray = @[timesArray[0], [NSString stringWithFormat:@"%@/%@", timesArray[1], timesArray[2]], timesArray[3]];
        }
    }
    for (int i = 0; i < timesArray.count; i++) {
        UILabel *label = [self.marketTimeBar viewWithTag:1000+i];
        if (!label) {
            label = [[UILabel alloc] init];
            label.tag = 1000+i;
            label.font = [UIFont systemFontOfSize:10];
            label.textColor = RGB_HEX(kAxisTextColor);
            [self.marketTimeBar addSubview:label];
        }
        label.text = timesArray[i];
        CGSize size = [label.text sizeWithAttributes:@{NSFontAttributeName: label.font}];
        CGFloat top = kTimeBarHeight - size.height;
        if (i==0) {
            label.frame = CGRectMake(0, top, size.width, size.height);
        } else if (i == 1) {
            label.frame = CGRectMake((self.marketTimeBar.frame.size.width - size.width)/2, top, size.width, size.height);
        } else {
            label.frame = CGRectMake(self.marketTimeBar.frame.size.width - size.width, top, size.width, size.height);
        }
    }
}

- (void)refreshUIWithData:(HACChartData *)data {
    _data = data;
    [self.nodeDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, HACChartNode* _Nonnull node, BOOL * _Nonnull stop) {
        [node setData:data];
        [node setNeedsDisplay];
    }];
}

- (void)refreshUI {
    [self.nodeDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, HACChartNode* _Nonnull node, BOOL * _Nonnull stop) {
        [node setNeedsDisplay];
    }];
}

- (void)endRefreshWithData:(HACChartData *)data {
    if (data) {
        _data = data;
        [self.nodeDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, HACChartNode* _Nonnull node, BOOL * _Nonnull stop) {
            [node setData:data];
        }];
    }
    [self.refreshIndicator stopAnimating];
    [self.contentScroll setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    _isRefresh = NO;
}

- (void)clearContents {
    _data = nil;
    [self hiddenFocusLayer];
    [self.nodeDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, HACChartNode * _Nonnull node, BOOL * _Nonnull stop) {
        [node clearNode];
        [node setNeedsDisplay];
    }];
}

- (void)setUp {
    
    self.focusEnable = YES;
    self.indexFromEnd = 0;
    self.focusItemsCount = 2;
    self.lastScale = 0;
    self.lastEndScale = 1.0;
    
    _focusComponent = [HACFocusComponents new];
    // 点击手势
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)];
    [self addGestureRecognizer:tapGesture];
    
    // 添加长按手势
    UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGesture:)];
    longPressGesture.delegate = self;
    longPressGesture.minimumPressDuration = 0.5;
    [self addGestureRecognizer:longPressGesture];
    
    // 添加缩放手势
    UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGesture:)];
    [self addGestureRecognizer:pinchGesture];
    
    // add contentView
    self.contentScroll.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    [self addSubview:self.contentScroll];
    
    _refreshIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    [self.contentScroll addSubview:_refreshIndicator];
    
    // 添加focus
    self.focusLayer = [[CAShapeLayer alloc] init];
    self.focusLayer.frame = self.bounds;
    self.focusLayer.backgroundColor = [[UIColor clearColor] CGColor];
    self.focusLayer.contentsScale = [[UIScreen mainScreen] scale];
    self.focusLayer.strokeColor = RGB_HEX(kFocusLineColor).CGColor;
    self.focusLayer.borderColor = [UIColor clearColor].CGColor;
    self.focusLayer.zPosition = 1;
    [self.layer addSublayer:self.focusLayer];
    self.focusPointLayer = [[CAShapeLayer alloc] init];
    self.focusPointLayer.frame = self.bounds;
    self.focusPointLayer.backgroundColor = [[UIColor clearColor] CGColor];
    self.focusPointLayer.contentsScale = [[UIScreen mainScreen] scale];
    self.focusPointLayer.strokeColor = RGB_HEX(kFocusPointColor).CGColor;
    self.focusPointLayer.fillColor = RGB_HEX(kFocusPointColor).CGColor;
    self.focusPointLayer.borderColor = [UIColor clearColor].CGColor;
    self.focusPointLayer.zPosition = 2;
    [self.layer addSublayer:self.focusPointLayer];
    //focus文字
    self.xCursorLabelUp = [self createCursorLabel];
    [self addSubview:self.xCursorLabelUp];
    self.xCursorLabelDown = [self createCursorLabel];
    [self addSubview:self.xCursorLabelDown];
    
    self.yCursorLabelLeft = [self createCursorLabel];
    [self addSubview:self.yCursorLabelLeft];
    self.yCursorLabelRight = [self createCursorLabel];
    [self addSubview:self.yCursorLabelRight];
}

- (UILabel*)createCursorLabel {
    UILabel *cursorLabel = [[UILabel alloc] init];
    cursorLabel.layer.zPosition = 9999;
    cursorLabel.font = [UIFont systemFontOfSize:8.0];
    
    cursorLabel.layer.masksToBounds = true;
    cursorLabel.layer.cornerRadius = 2;
    cursorLabel.layer.shouldRasterize = true;
    cursorLabel.layer.rasterizationScale = cursorLabel.layer.contentsScale;
    
    [cursorLabel setTextColor:RGB_HEX(kFocusLabelTextColor)];
    cursorLabel.backgroundColor = RGB_HEX(kFocusLabelBackColor);
    cursorLabel.textAlignment = NSTextAlignmentCenter;
    return cursorLabel;
}

- (void)setFrame:(CGRect)frame {
    [super setFrame:frame];
    self.marketTimeBar.frame = CGRectMake(0, frame.size.height - kTimeBarHeight, frame.size.width, kTimeBarHeight);
    self.contentScroll.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    self.refreshIndicator.center = CGPointMake(-refreshOffsetX+12, frame.size.height/2);
}

- (UIScrollView *)contentScroll {
    if (!_contentScroll) {
        _contentScroll = [[UIScrollView alloc] initWithFrame:CGRectZero];
        _contentScroll.backgroundColor = [UIColor clearColor];
        _contentScroll.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        _contentScroll.showsHorizontalScrollIndicator = NO;
        _contentScroll.showsVerticalScrollIndicator = NO;
        _contentScroll.alwaysBounceHorizontal = YES; // 保证可以滑动和最后回到offset为0
        _contentScroll.delegate = self;
//        _contentScroll.bounces = NO;
    }
    return _contentScroll;
}

#pragma mark - gestures
#pragma mark ----- UIGestureRecognizer
- (void)tapGesture:(UITapGestureRecognizer *)gesture {
    [self reactForTapGesture:gesture];
    [self hiddenFocusLayer];
    if ([self.delegate respondsToSelector:@selector(tapednodeComponent:gesture:)]) {
        [self.delegate tapednodeComponent:self gesture:gesture];
    }
}

- (void)longPressGesture:(UILongPressGestureRecognizer *)gesture {
    if (!self.focusEnable) {
        return;
    }
    if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged) {
        self.isFocusing = YES;
    } else {
        self.isFocusing = NO;
    }
    [self reactForLongPressGesture:gesture];
    [self drawingFocusLayer];
    if ([self.delegate respondsToSelector:@selector(dragnodeComponent:gesture:)]) {
        [self.delegate dragnodeComponent:self gesture:gesture];
    }
}

- (void)pinchGesture:(UIPinchGestureRecognizer *)gesture {
    [self reactForPinchGesture:gesture];
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    return YES;
}

#pragma mark -- scroll delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self reactForContentViewDidScroll:scrollView];
    if (scrollView.contentOffset.x < 0 && !self.isRefresh) {
        [self.refreshIndicator startAnimating];
        if (scrollView.contentOffset.x <= -refreshOffsetX) {
            self.isRefresh = YES;
            [self.contentScroll setContentInset:UIEdgeInsetsMake(0, refreshOffsetX, 0, 0)];
            if ([self.delegate respondsToSelector:@selector(nodeComponentNeedRefresh:)]) {
                [self.delegate nodeComponentNeedRefresh:self];
            }
        }
    }
}

#pragma mark - provider
- (NSArray *)focusDataInRect:(CGRect)rect focusIndex:(NSInteger)focusIndex {
    if (self.focusItemsCount == 0 || focusIndex == -1)
        return nil;
    NSMutableArray *focusDrawingData = [NSMutableArray array];
    CGFloat x = 0.0, y = 0.0;
    for (NSInteger i = 0; i < self.focusItemsCount; i++) {
        HACFocusComponents *item = [[HACFocusComponents alloc] init];
        item.index = i;
        item.axisType = i == 0 ? DrawingAxisTypeY : DrawingAxisTypeX; //第一根是竖线，第二根横线
        NSArray *textArray = [self stringForFocusItem:item focusIndex:focusIndex];
        item.text = (textArray&&textArray.count>0)?textArray.firstObject:@"";
        item.extText = (textArray&&textArray.count>1)?textArray.lastObject:@"";
        
        CGSize textSize = [item.text sizeWithAttributes:@{NSFontAttributeName : item.textFont}];
        CGRect frame = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), textSize.width , textSize.height);
        CGSize extTextSize = [item.extText sizeWithAttributes:@{NSFontAttributeName : item.textFont}];
        CGRect extFrame = CGRectMake(CGRectGetMaxX(rect)-extTextSize.width, CGRectGetMinY(rect), extTextSize.width , extTextSize.height);
        CGLine line = CGLineMake(0, 0, 0, 0);
        
        CGPoint focusPoint = self.focusPoint;
        
        if (item.axisType == DrawingAxisTypeX) {
            y = focusPoint.y;
            line = CGLineMake(CGRectGetMinX(rect) + textSize.width, y, CGRectGetMaxX(rect), y);
            frame.origin.y = MIN(CGRectGetMaxY(rect), MAX(CGRectGetMinY(rect), y - textSize.height / 2));
            extFrame.origin.y = frame.origin.y;
        } else {
            x = focusPoint.x;
            line = CGLineMake(x, CGRectGetMinY(rect), x, CGRectGetMaxY(rect));
            frame.origin.x = MIN(CGRectGetMaxX(rect) - textSize.width, MAX(CGRectGetMinX(rect), x - textSize.width / 2));
            frame.origin.y = CGRectGetMinY(rect);
            extFrame.origin.x = frame.origin.x;
            extFrame.origin.y = CGRectGetMaxY(rect) - textSize.height;
        }
        
        item.textFrame = frame;
        item.extTextFrame = extFrame;
        item.line = line;
        item.point = focusPoint;
        item.lineColor = self.focusComponent.lineColor?:item.lineColor;
        item.lineBolder = self.focusComponent.lineBolder?:item.lineBolder;
        item.borderWidth = self.focusComponent.borderWidth?:item.borderWidth;
        item.bgColor = self.focusComponent.bgColor?:item.bgColor;
        item.borderColor = self.focusComponent.bgColor?:item.bgColor;
        item.textFont = self.focusComponent.textFont?:item.textFont;
        item.textAlignment = self.focusComponent.textAlignment?:item.textAlignment;
        [focusDrawingData addObject:item];
    }
    return focusDrawingData;
}

- (NSArray<NSString *> *)stringForFocusItem:(HACFocusComponents *)focusItem focusIndex:(NSInteger)focusIndex {
    NSArray *retArray;
    if (focusItem.axisType == DrawingAxisTypeX) {
        retArray = @[@"X", @"X"];
    } else {
        retArray = @[@"Y", @"Y"];
    }
    return retArray;
}
#pragma  markt - drawing
- (void)activeFocusTimer:(BOOL)isActive {
    if (_focusTimer) {
        [_focusTimer invalidate];
        _focusTimer = nil;
    }
    if (isActive) {
        _focusTimer = [NSTimer timerWithTimeInterval:3 target:self selector:@selector(focusTimerFire:) userInfo:nil repeats:NO];
        [[NSRunLoop mainRunLoop] addTimer:_focusTimer forMode:NSRunLoopCommonModes];
    }
}

- (void)focusTimerFire:(NSTimer*)timer {
    [self hiddenFocusLayer];
}

- (void)hiddenFocusLayer {
    self.focusLayer.path = NULL;
    self.focusPointLayer.path = NULL;
    self.xCursorLabelUp.hidden = YES;
    self.xCursorLabelDown.hidden = YES;
    self.yCursorLabelLeft.hidden = YES;
    self.yCursorLabelRight.hidden = YES;
}

- (void)drawingFocusLayer {
    if (self.focusIndex == -1) {
        // 清除
        [self activeFocusTimer:YES];
    } else {
        [self activeFocusTimer:NO];
        self.xCursorLabelUp.hidden = NO;
        self.xCursorLabelDown.hidden = NO;
        self.yCursorLabelLeft.hidden = NO;
        self.yCursorLabelRight.hidden = NO;
        
        @autoreleasepool {
            CGMutablePathRef path = CGPathCreateMutable();
            //            CGRect offsetCenterFrame = [self offsetRectForOriginalRect:self.timeLineView.frame];
            CGRect offsetCenterFrame = self.bounds;
            NSArray *datas = [self focusDataInRect:offsetCenterFrame focusIndex:self.focusIndex];
            BOOL hasErrorData = NO;//排除错误显示数据
            for (HACFocusComponents *obj in datas) {
                UILabel *label = obj.axisType == DrawingAxisTypeX ? self.xCursorLabelUp : self.yCursorLabelLeft;
                if ([obj.text isEqualToString:@"0"]) {
                    hasErrorData = YES;
                    break;
                }
                label.text = obj.text;
                label.frame = obj.textFrame;
                label = obj.axisType == DrawingAxisTypeX ? self.xCursorLabelDown : self.yCursorLabelRight;
                label.text = obj.extText;
                label.frame = obj.extTextFrame;
                
                CGLine line = obj.line;
                if (obj.axisType == DrawingAxisTypeY) {
                    // y轴需要从最上面到最下面
                    line.start.y = 0;
                    line.end.y = CGRectGetMaxY(self.bounds);
                }
                
                if (obj.axisType == DrawingAxisTypeY) {//focus point
                    CGMutablePathRef pointPath = CGPathCreateMutable();
                    CGPathAddArc(pointPath, NULL, obj.point.x, obj.point.y, 2, 0, 2 * M_PI, NO);
                    self.focusPointLayer.path = pointPath;
                    CFRelease(pointPath);
                }
                CGPathMoveToPoint(path, NULL, line.start.x, line.start.y);
                CGPathAddLineToPoint(path, NULL, line.end.x, line.end.y);
                CGPathCloseSubpath(path);
            }
            if (!hasErrorData) {
                self.focusLayer.strokeColor = self.focusComponent.lineColor.CGColor;
                self.focusLayer.borderWidth = self.focusComponent.borderWidth;
                self.focusLayer.lineWidth = self.focusComponent.borderWidth;
                self.focusLayer.path = path;
            }
            CFRelease(path);
        }
    }
}

- (void)reactForTapGesture:(UITapGestureRecognizer *)gesture {}
- (void)reactForLongPressGesture:(UILongPressGestureRecognizer*)gesture {}
- (void)reactForPinchGesture:(UIPinchGestureRecognizer *)gesture {}
- (void)reactForContentViewDidScroll:(UIScrollView *)scrollView {}

- (void)updateContentScrollSize {
    __block HACChartNode *KNode;
    CGFloat __block maxWidth = self.frame.size.width;
    [self.nodeDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, HACChartNode* _Nonnull node, BOOL * _Nonnull stop) {
        if (node.maxContentWidth > maxWidth) {
            maxWidth = node.maxContentWidth;
        }
        KNode = node;
    }];
    
    self.contentScroll.contentSize = CGSizeMake(maxWidth, self.frame.size.height);
    CGFloat contentOffsetX = KNode.startIndex * KNode.singleWidth;
    self.contentScroll.contentOffset = CGPointMake(contentOffsetX, 0);
}
@end
